package com.resource.fxLoader
{
	import flash.display.DisplayObject;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.system.SecurityDomain;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import flash.utils.setTimeout;
	
	import org.osmf.events.LoadEvent;
	
	/**
	 * 自定义loader类
	 * 最多支持5线程
	 * @author xiezhicheng
	 */
	public final class ResouceManager extends EventDispatcher
	{
		private static var _instance:ResouceManager;
		/**加载器的数组*/
		private var _loadersArr:Array = [];
		private var _loadingKeys:Object = {};
	
		/**已加载的资源*/
		private var _loadDic:Dictionary = new Dictionary();
		/**正在加载资源的数组*/
		private var _loadingArr:Array = [] ;
		/**在资源加载中过滤相同请求*/
		private var loadingArr:Array = [];
		/**回调函数*/
		private var _callBackDic:Dictionary = new Dictionary();
		
		public function ResouceManager()
		{
			if (_instance == null) 
			{
				_instance = this;
				init();
			
			}else{
				throw new Error("MassLoader is a single class");
			}
			
		}
		
		/**
		 * 创建实例
		 * @return 
		 */
		public static function getInstance():ResouceManager
		{
			if (_instance == null) 
			{
				_instance = new ResouceManager();
			}	
			return _instance;
			
		}
		
		
		private function init():void
		{
		}
		
		
		/**
		 * 加载数据
		 * key - 地址
		 * process - 加载完成的回调函数
		 * */
		public function load(key:String,processListener:Function = null):void
		{
			if (loadingArr.indexOf(key) == -1) 
			{
				_loadingArr.push(key);
				loadingArr.push(key);
			}
			
			if(processListener != null)
				addCallBack(key,processListener);
			
			if (_loadDic[key] != null) //已有该资源,则不进行加载
			{
				var index:int = loadingArr.indexOf(key);
				loadingArr.splice(index,1);
				index = _loadingArr.indexOf(key);
				_loadingArr.splice(index,1);
				
				loadEventNotification(key);
			}
			else if (!_loadingKeys.hasOwnProperty(key))// 没有标示，则进行加载，有标示则表示正在加载 
			{
				_loadingKeys[key] = 0;
				beginLoad();
			}
		}
		
		
		/**
		 * 开始加载，如果没有可用加载器返回
		 * 如果没有找到key对应的资源信息则删除正在加载资源对象中的key
		 * */
		private function beginLoad():void
		{
			if (_loadingArr.length > 0) 
			{
				var loader:InternalLoader = getFreeLoader();
				if (loader) 
				{
					var key:String = _loadingArr.shift();
				
					loader.loadResource(key);
					loader.addEventListener(Event.CANCEL, onLoadComplete);
					loader.addEventListener(Event.COMPLETE, onLoadComplete);
					//loader.addEventListener(Event.COMPLETE,onLoadComplete);
				}
				else{
					trace("wait for a free loader");
				}			
			}	
			
		}
		
		
		/**
		 * 加载完成
		 * */
		protected function onLoadComplete(e:Event):void
		{
			var currentLoader:InternalLoader = e.currentTarget as InternalLoader;
			currentLoader.removeEventListener(Event.COMPLETE,onLoadComplete);
			currentLoader.removeEventListener(Event.CANCEL,onLoadComplete);
			
			var key:String = currentLoader.url;
			
			var index:int = loadingArr.indexOf(key);//删除加载中的key
			loadingArr.splice(index,1);
			
			if (_loadDic[key] == null) 
			{
				_loadDic[key] = currentLoader.data;//将数据放到数组里,
			}
			
			if (e.type == Event.COMPLETE) 
			{
				loadEventNotification(key);	
			}
			else//加载出现问题
			{
				delete _loadingKeys[key];
				loadEventNotification(key);
			}
			
			if (loadingArr.length > 0) //当等待加载队列中还有key,则继续进行加载
			{
				beginLoad();	
			}
			
			var isAllFree:Boolean = true;	//是否所有资源都加载完毕了
			for each(var ld:InternalLoader in _loadersArr)
			{
				if (ld.isLoading && ld != currentLoader) 
				{
					isAllFree = false;
					break;
				}
			}
			
			if (isAllFree) 
			{
				trace("all resources are load completed")
			}
		}
		
		
		/**
		 * 获取空闲的loader
		 * */
		private function getFreeLoader():InternalLoader
		{
			var isAllLoading:Boolean = true;
			for each(var ld:InternalLoader in _loadersArr)
			{
				//判断是否空闲
				if(!ld.isLoading)
				{
					isAllLoading = false;
					return ld;
				}
			}
			
			if (isAllLoading /*&& _loadersArr.length < 5*/) //并发数量(暂不作限制)
			{
				var newloader:InternalLoader = new InternalLoader();
				_loadersArr.push(newloader);
				
				return newloader;
			}
			
			return null;
		}
		
		
		/**
		 * 加载完成回调函数
		 * */
		private function loadEventNotification(key:String):void
		{
			if (_callBackDic[key]) 
			{
				if (loadingArr.length == 0) 
				{
				//	trace("finishLoading");
				//	dispatchEvent(new Event("finishLoading"));	
				}
				
				if (_callBackDic[key] != null) 
				{
					for each(var i:Function in _callBackDic[key])
					{
						if(i != null){
							i(_loadDic[key] as ByteArray);
						}
						
					}
					
					_callBackDic[key].length = 0;
				}
			}
		}
		
		
		/**
		 * 添加回调函数
		 * */
		private function addCallBack(key:String,processListener:Function):void
		{
			if(_callBackDic[key] == null)
				_callBackDic[key] = [];
			_callBackDic[key].push(processListener);
		}
		
	}
}